﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace BasicFramework.Factory
{
    public abstract class Factory
    {

        #region Fields

        #endregion


        #region Properties

        #endregion


        #region Constructors

        #endregion


        #region Events

        #endregion


        #region Methods

        protected static ConstructorInfo GetBestMatchingConstructor(Type type, object[] parameters)
        {
            // Get Type Constructors
            ConstructorInfo[] constructors = type.GetConstructors();

            List<ConstructorInfo> countMatches = new List<ConstructorInfo>();

            for (int i = 0; i < constructors.Length; i++)
            {
                // Check if Constructor has the same length as specified parameters
                if (constructors[i].GetParameters().Length == parameters.Length)
                {
                    countMatches.Add(constructors[i]);
                }
            }

            ConstructorInfo bestMatch = constructors[0];

            if (countMatches.Count > 0)
            {
                int indexOfBest = -1;
                int currentBestMatches = -1;

                for (int i = 0; i < countMatches.Count; i++)
                {
                    // Get Parameter infos
                    ParameterInfo[] pi = countMatches[i].GetParameters();

                    // Matching Parameters types count
                    int n = 0;

                    for (int j = 0; j < pi.Length; j++)
                    {
                        if (pi[j].ParameterType.Equals(parameters[j].GetType()))
                        {
                            n++;
                        }
                    }
                    // Check if constructor matches better
                    if (n > currentBestMatches)
                    {
                        currentBestMatches = n;

                        indexOfBest = i;
                    }
                }

                bestMatch = countMatches[indexOfBest];
            }

            return bestMatch;
        }

        #endregion

    }
}
